using System;
using System.Collections.Generic;
using System.Globalization;
using System.Security;
using System.Threading;
using Oracle.ManagedDataAccess.Client;
using OracleInternal.BinXml;
using OracleInternal.Common;
using OracleInternal.Network;
using OracleInternal.ServiceObjects;

namespace OracleInternal.ConnectionPool
{
	internal class OraclePoolManager : PoolManager<OraclePoolManager, OraclePool, OracleConnectionImpl>
	{
		private static int s_maxBucketCapacity = 4;

		private static int s_maxListCapacity = 10;

		private const int DEFAULT_MAX_ELEMS_IN_METADATAPOOL_TUNING_OFF = 200;

		private const int DEFAULT_MAX_ELEMS_IN_METADATAPOOL_TUNING_ON = 50;

		private const int DEFAULT_MAX_ELEMS_IN_SQLPARSEINFOPOOL_TUNING_OFF = 200;

		private const int DEFAULT_MAX_ELEMS_IN_SQLPARSEINFOPOOL_TUNING_ON = 50;

		private const int DEFAULT_MAX_ELEMS_IN_METADATAPOOL = 1000;

		private const int DEFAULT_MAX_ELEMS_IN_SQLPARSEINFOPOOL = 500;

		internal const int DEFAULT_MAX_ELEMS_IN_DERIVEPARAMINFOPOOL = 50;

		internal const int DEFAULT_MAX_ELEMS_IN_XMLSCHEMAPOOL = 200;

		private const int DEFAULT_MAX_ELEMS_IN_XMLTOKENPOOL = 4096;

		public OraBufPool m_oraBufPool;

		internal SyncDictionary<string, DeriveParamInfoPool> m_dictDeriveParamInfoPool;

		internal object m_dictDeriveParamInfoPoolLock = new object();

		internal SyncDictionary<string, XmlSchemaPool> m_dictXmlSchemaPool;

		internal object m_dictXmlSchemaPoolLock = new object();

		internal object m_orclGlobLock = new object();

		internal int m_appThreadLCID = 1033;

		internal static int NUM_CRED_RETRIEVAL_TRIES = 3;

		internal long m_logonMode;

		internal bool m_bDoNAHandShake;

		internal bool m_bDoExternalAuth;

		internal bool m_maxOpenCursorsFetched;

		internal ObxmlTokenManager m_xmlTokenManager;

		internal TableColumnsCache m_tableColumnsCache;

		private SyncDictionary<string, SQLLocalParsePrimaryKeyInfoPool> m_dictStatementmetadatacache;

		private object m_dictStatementmetadatacacheLock = new object();

		private SQLParseInfoPool m_sqlParseInfoPool;

		private bool m_isDisposed;

		internal bool m_bSelfTuning;

		private object m_tuningLock = new object();

		internal int m_recommendedSCS;

		private int m_maxAllowedCursors = int.MaxValue;

		public int MaxAllowedValue
		{
			get
			{
				return m_maxAllowedCursors;
			}
			set
			{
				if (m_maxAllowedCursors != value)
				{
					m_maxAllowedCursors = value;
				}
			}
		}

		public string ID
		{
			get
			{
				if (m_cs != null)
				{
					return m_cs.m_pmId;
				}
				return string.Empty;
			}
		}

		internal override void Initialize(ConnectionString cs, OracleConnection con)
		{
			base.Initialize(cs, con);
			if (cs.m_conPoolKey == null)
			{
				m_conPoolKey = new ConnectionPoolId(cs.m_pmId, cs.m_orclCredential);
				cs.m_conPoolKey = m_conPoolKey;
			}
			else
			{
				m_conPoolKey = cs.m_conPoolKey;
			}
			m_appThreadLCID = CultureInfo.CurrentCulture.LCID;
			int num = m_cs.m_maxPoolSize;
			if (num > 200)
			{
				num = 200;
			}
			m_oraBufPool = new OraBufPool(num * s_maxListCapacity);
			m_bSelfTuning = m_cs.m_selfTuning && m_cs.m_pooling;
			m_recommendedSCS = ((!m_bSelfTuning) ? m_cs.m_stmtCacheSize : ProviderConfig.MaxStatementCacheSize.Value);
			if (m_cs.m_metadataPooling)
			{
				if (m_dictStatementmetadatacache == null)
				{
					m_dictStatementmetadatacache = new SyncDictionary<string, SQLLocalParsePrimaryKeyInfoPool>();
				}
				if (m_dictDeriveParamInfoPool == null)
				{
					m_dictDeriveParamInfoPool = new SyncDictionary<string, DeriveParamInfoPool>();
				}
				if (m_dictXmlSchemaPool == null)
				{
					m_dictXmlSchemaPool = new SyncDictionary<string, XmlSchemaPool>();
				}
			}
			if (m_sqlParseInfoPool == null)
			{
				m_sqlParseInfoPool = new SQLParseInfoPool(500);
			}
			if (m_xmlTokenManager == null && ConfigBaseClass.m_XMLTypeClientSideDecoding)
			{
				m_xmlTokenManager = new ObxmlTokenManager(this);
			}
			if (m_cs.m_pooling)
			{
				InitializeSEPSCredentials();
			}
			if (m_tableColumnsCache == null)
			{
				m_tableColumnsCache = new TableColumnsCache();
			}
		}

		internal void InitializeSEPSCredentials()
		{
			SqlNetOraConfig sqlNetOraConfig = new SqlNetOraConfig(ConfigBaseClass.m_configParameters);
			string text = null;
			string text2 = null;
			if (m_cs.m_userId != "/")
			{
				text = m_cs.m_userId;
			}
			if (m_cs.m_proxyUserId != "/")
			{
				text2 = m_cs.m_proxyUserId;
			}
			if (m_cs.m_dbaPrivilege == OracleDBAPrivilege.SYSDBA)
			{
				m_logonMode |= 32L;
				m_bDoExternalAuth = (m_bDoNAHandShake = true);
			}
			else if (m_cs.m_dbaPrivilege == OracleDBAPrivilege.SYSOPER)
			{
				m_logonMode |= 64L;
				m_bDoExternalAuth = (m_bDoNAHandShake = true);
			}
			else if (m_cs.m_dbaPrivilege == OracleDBAPrivilege.SYSASM)
			{
				m_logonMode |= 4194304L;
			}
			else if (m_cs.m_dbaPrivilege == OracleDBAPrivilege.SYSBACKUP)
			{
				m_logonMode |= 16777216L;
			}
			else if (m_cs.m_dbaPrivilege == OracleDBAPrivilege.SYSDG)
			{
				m_logonMode |= 33554432L;
			}
			else if (m_cs.m_dbaPrivilege == OracleDBAPrivilege.SYSKM)
			{
				m_logonMode |= 67108864L;
			}
			else if (m_cs.m_dbaPrivilege == OracleDBAPrivilege.SYSRAC)
			{
				m_logonMode |= 134217728L;
			}
			if (m_bDoExternalAuth || (!("/" == m_cs.m_userId) && !("/" == m_cs.m_proxyUserId)))
			{
				return;
			}
			if (!sqlNetOraConfig.WalletOverride)
			{
				m_bDoExternalAuth = (m_bDoNAHandShake = true);
				return;
			}
			m_bDoExternalAuth = false;
			string seps_userId = null;
			SecureString seps_secure_password = null;
			string walletPath = null;
			string walletFile = null;
			FetchSEPSCredentails(m_cs.m_dataSource, out seps_userId, out seps_secure_password, out walletPath, out walletFile);
			if ("/" == m_cs.m_userId)
			{
				text = (m_cs.m_sepsUserId = seps_userId);
				m_cs.m_sepsSecuredPassword = seps_secure_password;
				m_bSEPSForProxyCredentials = false;
			}
			else if ("/" == m_cs.m_proxyUserId)
			{
				text2 = (m_cs.m_sepsProxyUserId = seps_userId);
				m_cs.m_sepsSecuredProxyPassword = seps_secure_password;
				m_bSEPSForProxyCredentials = true;
			}
			m_bUsingSEPSCredentials = true;
			m_bSEPSCredentialsFetched = true;
			Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.InitializeSEPSCredentials, "InitializeSEPSCredentials => SEPS credentials stored in the PM CACHE for PM: " + m_id);
			if (!OracleConnectionDispenser<OraclePoolManager, OraclePool, OracleConnectionImpl>.s_bSEPSFileWatcherCreated)
			{
				OracleConnectionDispenser<OraclePoolManager, OraclePool, OracleConnectionImpl>.CreateSEPSFileWatcher(walletPath, walletFile);
			}
		}

		internal static void FetchSEPSCredentails(string ds, out string seps_userId, out SecureString seps_secure_password, out string walletPath, out string walletFile)
		{
			seps_userId = null;
			seps_secure_password = null;
			walletPath = null;
			walletFile = null;
			for (int i = 0; i < NUM_CRED_RETRIEVAL_TRIES; i++)
			{
				try
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.FetchSEPSCredentails, "FetchSEPSCredentails => Querying Data Source (TRIAL: {0}): {1}", i.ToString(), ds);
					OracleCommunication.GetSEPSUserIDandPW(ds, out seps_userId, out seps_secure_password, out walletPath, out walletFile);
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.FetchSEPSCredentails, "FetchSEPSCredentails => Got Credentials from Client Wallet");
					return;
				}
				catch (Exception ex)
				{
					Trace.Write(OracleTraceLevel.Private, OracleTraceTag.CP, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.FetchSEPSCredentails, "FetchSEPSCredentails => Exception (TRIAL: {0}): {1}", i.ToString(), ex.ToString());
					if (i < NUM_CRED_RETRIEVAL_TRIES)
					{
						Thread.Sleep(200);
					}
				}
			}
		}

		internal override void InitializeSelfTuning()
		{
			if (m_cs != null && m_cs.m_selfTuning && m_cs.m_pooling && !m_bSelfTuningDisabled)
			{
				m_bSelfTuning = true;
			}
		}

		public override void MarkAllPRsForDeletion(DateTime haEventUtcDateTime, bool isHAEvnt = false)
		{
			base.MarkAllPRsForDeletion(haEventUtcDateTime, isHAEvnt);
		}

		public override void ClearAllPools(OracleConnectionImpl pr, bool isHAEvnt = false)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.ClearAllPools);
			}
			try
			{
				base.ClearAllPools(pr, isHAEvnt);
				if (m_xmlTokenManager != null)
				{
					m_xmlTokenManager.PurgeTokenMaps(null, -1);
					m_xmlTokenManager.Dispose();
					m_xmlTokenManager = null;
				}
				if (m_tableColumnsCache != null)
				{
					m_tableColumnsCache.Clear();
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.ClearAllPools, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.ClearAllPools);
				}
			}
		}

		internal override bool Close(OracleConnectionImpl con, OracleConnection connRefForCriteria, bool isConnectionCheckedout = false)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.Close);
			}
			try
			{
				return base.Close(con, connRefForCriteria, isConnectionCheckedout);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.Close, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.Close);
				}
			}
		}

		public override OracleConnectionImpl CreateNewPR(int reqCount, bool bForPoolPopulation, ConnectionString csWithDiffOrNewPwd, OracleConnection connRefForCriteria, string instanceName = null, List<string> switchFailedInstNames = null)
		{
			OracleConnectionImpl oracleConnectionImpl = base.CreateNewPR(reqCount, bForPoolPopulation, csWithDiffOrNewPwd, connRefForCriteria, instanceName, switchFailedInstNames);
			if (oracleConnectionImpl != null)
			{
				bool flag = false;
				if (connRefForCriteria != null)
				{
					flag = connRefForCriteria.ShardingKey != null || connRefForCriteria.SuperShardingKey != null;
				}
				else if (m_shardRoutingCache != null)
				{
					flag = true;
				}
				if (flag && m_cs != null && m_cs.m_pooling)
				{
					if (m_databaseName == null)
					{
						m_databaseName = oracleConnectionImpl.m_databaseName;
						m_databaseDomainName = oracleConnectionImpl.m_databaseDomainName;
					}
					AddTopology(oracleConnectionImpl);
				}
			}
			return oracleConnectionImpl;
		}

		public override OracleConnectionImpl GetUsingDiffPassword(ConnectionString csWithDiffPassword, OracleConnection connRefForCriteria)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.GetUsingDiffPassword);
			}
			try
			{
				return base.GetUsingDiffPassword(csWithDiffPassword, connRefForCriteria);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.GetUsingDiffPassword, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.GetUsingDiffPassword);
				}
			}
		}

		public override OracleConnectionImpl Get(ConnectionString csWithNewPassword, bool bGetForApp, OracleConnection connRefForCriteria, string affinityInstanceName = null, bool bForceMatch = false)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.Get);
			}
			OracleConnectionImpl oracleConnectionImpl = null;
			try
			{
				while (oracleConnectionImpl == null)
				{
					oracleConnectionImpl = base.Get(csWithNewPassword, bGetForApp, connRefForCriteria, affinityInstanceName, bForceMatch);
					if (!oracleConnectionImpl.m_bConnected)
					{
						oracleConnectionImpl = null;
						continue;
					}
					bool flag = true;
					lock (oracleConnectionImpl)
					{
						if (!oracleConnectionImpl.m_bConnected)
						{
							oracleConnectionImpl = null;
							continue;
						}
						if (base.ConnectionString.m_validateConnection)
						{
							try
							{
								flag = oracleConnectionImpl.PingServer();
							}
							catch
							{
								flag = false;
							}
						}
						else
						{
							if (flag && (oracleConnectionImpl.m_deletionRequestor == DeletionRequestor.HA || (oracleConnectionImpl.m_cp != null && oracleConnectionImpl.m_cp.m_bInstanceDown)))
							{
								flag = false;
							}
							if (flag && oracleConnectionImpl.m_cs.m_pooling)
							{
								try
								{
									flag = oracleConnectionImpl.m_oracleCommunication.TransportAlive;
								}
								catch
								{
									flag = false;
								}
							}
						}
						if (!flag)
						{
							if (ProviderConfig.m_bTraceLevelPrivate)
							{
								string str = $"({oracleConnectionImpl.m_endUserSessionId}:{oracleConnectionImpl.m_endUserSerialNum})";
								Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.Get, str + " : (HA) Setting pr.m_deletionRequestor = DeletionRequestor.HA");
							}
							oracleConnectionImpl.m_deletionRequestor = DeletionRequestor.HA;
							Close(oracleConnectionImpl, null, isConnectionCheckedout: true);
							oracleConnectionImpl = null;
						}
						goto IL_0132;
					}
					IL_0132:
					if (oracleConnectionImpl == null || ((m_cs.m_orclCredential == null || !m_cs.m_orclCredential.m_bProxyUserIdSet) && !m_cs.m_bProxyUserIdSet))
					{
						continue;
					}
					if (oracleConnectionImpl.m_sessionType == SessionType.Two_Session_Proxy && !oracleConnectionImpl.m_bEndUserSessionEstablished)
					{
						oracleConnectionImpl.OpenEndUserSession(csWithNewPassword.m_userId, csWithNewPassword.m_securedPassword, connRefForCriteria);
						oracleConnectionImpl.m_cs = csWithNewPassword;
					}
					else if (oracleConnectionImpl.m_cs.m_userId != csWithNewPassword.m_userId || (connRefForCriteria != null && !connRefForCriteria.m_bNewConCreated && !connRefForCriteria.CanReturnBestMatchingPR()))
					{
						oracleConnectionImpl.m_statementCache.Purge();
						if (oracleConnectionImpl.m_sessionType == SessionType.Two_Session_Proxy)
						{
							oracleConnectionImpl.CloseEndUserSession();
							oracleConnectionImpl.OpenEndUserSession(csWithNewPassword.m_userId, csWithNewPassword.m_securedPassword, connRefForCriteria);
							oracleConnectionImpl.m_cs = csWithNewPassword;
						}
						else
						{
							oracleConnectionImpl.m_bCheckedOutByApp = false;
							oracleConnectionImpl.m_deletionRequestor = DeletionRequestor.Put;
							Close(oracleConnectionImpl, connRefForCriteria);
							oracleConnectionImpl = GetNew(csWithNewPassword, connRefForCriteria, affinityInstanceName);
							ProcessCriteriaCtxAndAlterSessionIfReqd(connRefForCriteria, oracleConnectionImpl);
						}
					}
				}
				if (oracleConnectionImpl != null && oracleConnectionImpl.m_pm != null && oracleConnectionImpl.m_pm.m_bSelfTuning)
				{
					if (m_recommendedSCS == 0 && oracleConnectionImpl.m_statementCache != null)
					{
						oracleConnectionImpl.PurgeStatementCache();
						oracleConnectionImpl.m_statementCache.m_maxCacheSize = m_recommendedSCS;
						m_dictStatementmetadatacache = null;
						m_dictDeriveParamInfoPool = null;
						m_sqlParseInfoPool = null;
					}
					else
					{
						float num = 0.95f;
						if (oracleConnectionImpl.m_statementCache != null && (oracleConnectionImpl.m_statementCache.m_maxCacheSize < m_recommendedSCS || (float)oracleConnectionImpl.m_statementCache.m_maxCacheSize * num >= (float)m_recommendedSCS))
						{
							if (oracleConnectionImpl.m_statementCache.m_maxCacheSize > m_recommendedSCS)
							{
								oracleConnectionImpl.PurgeStatementCache(m_recommendedSCS);
							}
							oracleConnectionImpl.m_statementCache.m_maxCacheSize = m_recommendedSCS;
						}
					}
				}
				return oracleConnectionImpl;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.Get, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.Get, Trace.GetCPInfo(oracleConnectionImpl, null, null, null));
				}
			}
		}

		public override void Put(OracleConnectionImpl con, OracleConnection connRefForCriteria)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.Put);
			}
			try
			{
				if (!m_cs.m_pooling && SessionType.Two_Session_Proxy == con.SessionType)
				{
					con.CloseEndUserSession();
				}
				if (m_cs.m_stmtCachePurge && con.m_statementCache != null)
				{
					con.PurgeStatementCache();
				}
				con.m_oracleCommunication.OraBufPool.Init(con.m_oracleCommunication);
				base.Put(con, connRefForCriteria);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.Put, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.Put);
				}
			}
		}

		public override bool RemoveCheckedInPR(OracleConnectionImpl pr, bool bForce)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.RemoveCheckedInPR);
			}
			try
			{
				bool num = base.RemoveCheckedInPR(pr, bForce);
				if (num)
				{
					if (OraclePool.m_bPerfNumberOfFreeConnections)
					{
						OraclePool.PerformanceCounterDecrement(OraclePerfParams.CounterIndex.NumberOfFreeConnections, pr, pr.m_cp);
					}
					if (OraclePool.m_bPerfNumberOfPooledConnections)
					{
						OraclePool.PerformanceCounterDecrement(OraclePerfParams.CounterIndex.NumberOfPooledConnections, pr, pr.m_cp);
					}
					if (pr.m_cp.m_cpListPR.Count == 0)
					{
						if (OraclePool.m_bPerfNumberOfActiveConnectionPools)
						{
							OraclePool.PerformanceCounterDecrement(OraclePerfParams.CounterIndex.NumberOfActiveConnectionPools, pr, pr.m_cp);
						}
						if (OraclePool.m_bPerfNumberOfInactiveConnectionPools)
						{
							OraclePool.PerformanceCounterIncrement(OraclePerfParams.CounterIndex.NumberOfInactiveConnectionPools, pr, pr.m_cp);
						}
						pr.m_cp.m_bIsPoolActive = false;
					}
				}
				return num;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.RemoveCheckedInPR, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.RemoveCheckedInPR);
				}
			}
		}

		public override bool RemoveCheckedOutPR(OracleConnectionImpl pr, bool bForce)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.RemoveCheckedOutPR);
			}
			try
			{
				bool num = base.RemoveCheckedOutPR(pr, bForce);
				if (num && pr.m_cp != null)
				{
					if (OraclePool.m_bPerfNumberOfPooledConnections)
					{
						OraclePool.PerformanceCounterDecrement(OraclePerfParams.CounterIndex.NumberOfPooledConnections, pr, pr.m_cp);
					}
					if (pr.m_cp.m_cpListPR.Count == 0)
					{
						if (OraclePool.m_bPerfNumberOfActiveConnectionPools)
						{
							OraclePool.PerformanceCounterDecrement(OraclePerfParams.CounterIndex.NumberOfActiveConnectionPools, pr, pr.m_cp);
						}
						if (OraclePool.m_bPerfNumberOfInactiveConnectionPools)
						{
							OraclePool.PerformanceCounterIncrement(OraclePerfParams.CounterIndex.NumberOfInactiveConnectionPools, pr, pr.m_cp);
						}
						pr.m_cp.m_bIsPoolActive = false;
					}
				}
				return num;
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.RemoveCheckedOutPR, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.RemoveCheckedOutPR);
				}
			}
		}

		internal bool TryRetrieveLocalParseInfoFromCache(string serviceName, string cmdText, ref SQLMetaData sqlMetaData)
		{
			if (string.IsNullOrWhiteSpace(cmdText) || sqlMetaData == null || m_dictStatementmetadatacache == null)
			{
				return false;
			}
			if (sqlMetaData.m_sqlMetaInfo != null && sqlMetaData.m_sqlMetaInfo.bIsPooled)
			{
				return sqlMetaData.m_sqlMetaInfo.bStmtParsed;
			}
			if (!m_dictStatementmetadatacache.ContainsKey(serviceName))
			{
				return false;
			}
			SQLLocalParsePrimaryKeyInfo sQLLocalParsePrimaryKeyInfo = m_dictStatementmetadatacache[serviceName].Get(cmdText);
			if (sQLLocalParsePrimaryKeyInfo == null)
			{
				return false;
			}
			sqlMetaData.m_sqlMetaInfo = sQLLocalParsePrimaryKeyInfo;
			sqlMetaData.bStmtParsed = sQLLocalParsePrimaryKeyInfo.bStmtParsed;
			sqlMetaData.bPkFetched = sQLLocalParsePrimaryKeyInfo.bPkFetched;
			return sqlMetaData.bStmtParsed;
		}

		internal bool TryRetrievePrimaryKeyInfoFromCache(string serviceName, string cmdText, ref SQLMetaData sqlMetaData)
		{
			if (string.IsNullOrWhiteSpace(cmdText) || sqlMetaData == null || m_dictStatementmetadatacache == null)
			{
				return false;
			}
			if (sqlMetaData.m_sqlMetaInfo != null && sqlMetaData.m_sqlMetaInfo.bIsPooled)
			{
				return sqlMetaData.m_sqlMetaInfo.bPkFetched;
			}
			if (!m_dictStatementmetadatacache.ContainsKey(serviceName))
			{
				return false;
			}
			SQLLocalParsePrimaryKeyInfo sQLLocalParsePrimaryKeyInfo = m_dictStatementmetadatacache[serviceName].Get(cmdText);
			if (sQLLocalParsePrimaryKeyInfo == null)
			{
				return false;
			}
			sqlMetaData.m_sqlMetaInfo = sQLLocalParsePrimaryKeyInfo;
			sqlMetaData.bPkFetched = sQLLocalParsePrimaryKeyInfo.bPkFetched;
			sqlMetaData.bStmtParsed = sQLLocalParsePrimaryKeyInfo.bStmtParsed;
			return sqlMetaData.bPkFetched;
		}

		internal void TryCacheLocalParsePrimaryKeyInfo(string serviceName, string cmdText, SQLMetaData sqlMetaData)
		{
			if (string.IsNullOrWhiteSpace(cmdText) || sqlMetaData == null || m_dictStatementmetadatacache == null || sqlMetaData.m_sqlMetaInfo == SQLLocalParsePrimaryKeyInfo.Null || sqlMetaData.m_sqlMetaInfo == null || sqlMetaData.m_sqlMetaInfo.bIsPooled)
			{
				return;
			}
			if (!m_dictStatementmetadatacache.ContainsKey(serviceName))
			{
				lock (m_dictStatementmetadatacacheLock)
				{
					if (!m_dictStatementmetadatacache.ContainsKey(serviceName))
					{
						m_dictStatementmetadatacache[serviceName] = new SQLLocalParsePrimaryKeyInfoPool(1000);
					}
				}
			}
			m_dictStatementmetadatacache[serviceName].Put(cmdText, sqlMetaData.m_sqlMetaInfo);
		}

		internal bool TryGetSqlWithRowId(ref string cmdText, out bool hadRowId, out bool addedRowId)
		{
			hadRowId = (addedRowId = false);
			if (m_sqlParseInfoPool == null)
			{
				return false;
			}
			string text = m_sqlParseInfoPool.Get(cmdText, out hadRowId);
			if (text != null)
			{
				addedRowId = !text.Equals(cmdText);
				cmdText = text;
				return true;
			}
			return false;
		}

		internal void CacheSqlWithRowIdInfo(string cmdText, string cmdTextWithRowId, bool hasRowId)
		{
			if (m_sqlParseInfoPool != null)
			{
				m_sqlParseInfoPool.Put(cmdText, cmdTextWithRowId, hasRowId);
			}
		}

		~OraclePoolManager()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.dtor);
			}
			try
			{
				try
				{
					Dispose();
				}
				catch (Exception ex)
				{
					OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.dtor, ex);
					throw;
				}
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.dtor);
				}
			}
		}

		internal void Dispose()
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2304, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.Dispose);
			}
			try
			{
				if (!m_isDisposed)
				{
					m_isDisposed = true;
					GC.SuppressFinalize(this);
				}
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)268437504, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.Dispose, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)2560, OracleTraceClassName.OraclePoolManager, OracleTraceFuncName.Dispose);
				}
			}
		}

		internal void AddTopology(OracleConnectionImpl connImpl)
		{
			if (m_shardRoutingCache == null)
			{
				CreateSharedShardRoutingCache(connImpl);
			}
			if (m_shardRoutingCache != null)
			{
				m_shardRoutingCache.OnConnectionCreation(connImpl);
			}
		}
	}
}
